const { asClass, asValue, createContainer, asFunction } = require('awilix')

const container = createContainer()

const Application = require('./app/Application')
const Server = require('./interfaces/http/Server')
const config = require('./infra/config')
const database = require('./infra/orm/sequelize')
const router = require('./interfaces/http/router')
const logger = require('./infra/logger')

const nacos = require('./infra/nacos')
const redis = require('./infra/redis')
container.register({
  server: asClass(Server).singleton(),
  app: asClass(Application).singleton(),
  config: asValue(config),
  database: asFunction(database).singleton(),
  router: asFunction(router).singleton(),
  logger: asFunction(logger).singleton(),
  nacos: asFunction(nacos).singleton(),
  redis: asFunction(redis).singleton(),
})

const { scopePerRequest } = require('awilix-express')
const errorHandle = require('./interfaces/http/middleware/errorHandle')
const filterMiddleware = require('./interfaces/http/middleware/filter')
const parseIntMiddleware = require('./interfaces/http/middleware/parseInt')
const jwt = require('./interfaces/http/middleware/jwt')
const loginUser = require('./interfaces/http/middleware/loginUser')
container.register({
  containerMiddleware: asValue(scopePerRequest(container)),
  errorHandle: asValue(errorHandle),
  filterMiddleware: asValue(filterMiddleware),
  parseIntMiddleware: asValue(parseIntMiddleware),
  jwt: asFunction(jwt).singleton(),
  loginUser: asFunction(loginUser).singleton(),
})

// 认证子域
const register = require('./app/auth/Register')
const login = require('./app/auth/Login')
const GetUserInfo = require('./app/auth/GetUserInfo')
const GetAuthMenu = require('./app/auth/GetAuthMenu')
const ModifyPassword = require('./app/auth/ModifyPassword')
container.register({
  register: asClass(register).singleton(),
  login: asClass(login).singleton(),
  getUserInfo: asClass(GetUserInfo).singleton(),
  getAuthMenu: asClass(GetAuthMenu).singleton(),
  modifyPassword: asClass(ModifyPassword).singleton(),
})

// 用户子域
const UserRepository = require('./infra/repository/user/sequelizeUserRepo')
const userCoverter = require('./infra/coverter/userCoverter')
const CreateUser = require('./app/user/CreateUser')
const GetUserPage = require('./app/user/GetUserPage')
const GetUserDetail = require('./app/user/GetUserDetail')
const DisableUser = require('./app/user/DisableUser')
const UpdateUser = require('./app/user/UpdateUser')
const EnableUser = require('./app/user/EnableUser')
const DeleteUser = require('./app/user/DeleteUser')
const ResetPassword = require('./app/user/ResetPassword')
const SetSuperAdmin = require('./app/user/SetSuperAdmin')
container.register({
  userRepo: asClass(UserRepository).singleton(),
  userCoverter: asValue(userCoverter),
  createUser: asClass(CreateUser).singleton(),
  getUserPage: asClass(GetUserPage).singleton(),
  getUserDetail: asClass(GetUserDetail).singleton(),
  disableUser: asClass(DisableUser).singleton(),
  enableUser: asClass(EnableUser).singleton(),
  updateUser: asClass(UpdateUser).singleton(),
  removeUser: asClass(DeleteUser).singleton(),
  setSuperAdmin: asClass(SetSuperAdmin).singleton(),
  resetPassword: asClass(ResetPassword).singleton(),
})

// 角色子域
const roleCoverter = require('./infra/coverter/roleCoverter')
const RoleRepository = require('./infra/repository/role/sequelizeRoleRepo')
const GetRoleDetail = require('./app/role/GetRoleDetail')
const GetRolePage = require('./app/role/GetRolePage')
const CreateRole = require('./app/role/CreateRole')
const UpdateRole = require('./app/role/UpdateRole')
const DeleteRole = require('./app/role/DeleteRole')
const RoleAuthorization = require('./app/role/RoleAuthorization')
container.register({
  roleCoverter: asValue(roleCoverter),
  roleRepo: asClass(RoleRepository).singleton(),
  getRoleDetail: asClass(GetRoleDetail).singleton(),
  getRolePage: asClass(GetRolePage).singleton(),
  createRole: asClass(CreateRole).singleton(),
  updateRole: asClass(UpdateRole).singleton(),
  deleteRole: asClass(DeleteRole).singleton(),
  roleAuthorization: asClass(RoleAuthorization).singleton(),
})

// 系统子域
const systemCoverter = require('./infra/coverter/systemCoverter')
const SystemRepository = require('./infra/repository/system/sequelizeSystemRepo')
const GetSystemDetail = require('./app/system/GetSystemDetail')
const GetSystemPage = require('./app/system/GetSystemPage')
const CreateSystem = require('./app/system/CreateSystem')
const UpdateSystem = require('./app/system/UpdateSystem')
const DeleteSystem = require('./app/system/DeleteSystem')
container.register({
  systemCoverter: asValue(systemCoverter),
  systemRepo: asClass(SystemRepository).singleton(),
  getSystemDetail: asClass(GetSystemDetail).singleton(),
  getSystemPage: asClass(GetSystemPage).singleton(),
  createSystem: asClass(CreateSystem).singleton(),
  updateSystem: asClass(UpdateSystem).singleton(),
  deleteSystem: asClass(DeleteSystem).singleton(),
})

// 菜单子域
const menuCoverter = require('./infra/coverter/menuCoverter')
const MenuRepository = require('./infra/repository/menu/sequelizeMenuRepo')
const GetMenuTree = require('./app/menu/GetMenuTree')
const GetMenuDetail = require('./app/menu/GetMenuDetail')
const CreateMenu = require('./app/menu/CreateMenu')
const UpdateMenu = require('./app/menu/UpdateMenu')
const DeleteMenu = require('./app/menu/DeleteMenu')
container.register({
  menuCoverter: asValue(menuCoverter),
  menuRepo: asClass(MenuRepository).singleton(),
  getMenuTree: asClass(GetMenuTree).singleton(),
  getMenuDetail: asClass(GetMenuDetail).singleton(),
  createMenu: asClass(CreateMenu).singleton(),
  updateMenu: asClass(UpdateMenu).singleton(),
  deleteMenu: asClass(DeleteMenu).singleton(),
})

const listener = require('./interfaces/http/listeners')
container.register({
  listener: asFunction(listener).singleton(),
})

module.exports = container
